package adventure.commands;

import adventure.*;
import player.*;
import adventure.placeable.Item;
import adventure.misc.Currency;
import colour.ColourUtil;

/**
 *
 * @author Michael Hanns
 *
 */
public class Give extends AbstractCommand {

    Currency currency;

    public Give(Adventure a) {
        super(a, new String[]{"GIVE"});
        this.currency = a.getCurrency();
    }

    @Override
    public String validateAndExecute(Player p, String[] args) {
        if (args.length == 1) {
            return "Give what to whom?";
        } else if (((AdventureEdit) adv).getRoomManager().isLightPresent(p.x(), p.y(), p.z())) {
            int toPosition = 0;
            for (int x = 0; x < args.length; x++) {
                if (args[x].equalsIgnoreCase("to")) {
                    toPosition = x;
                }
            }

            if (args.length > 1 && toPosition > 1 && toPosition < args.length - 1) {
                String item = args[1];
                for (int x = 2; x < toPosition; x++) {
                    item = item.concat(" ".concat(args[x]));
                }

                String target = args[toPosition + 1];

                for (int x = toPosition + 2; x < args.length; x++) {
                    target = target.concat(" ".concat(args[x]));
                }
                return give(p, item, target);
            }

            return "Give what to whom?\nSyntax: give <item> to <player>";
        } else {
            return "You cannot see anything in the darkness!";
        }
    }

    private String give(Player player, String object, String target) {
        int x = player.x();
        int y = player.y();
        int z = player.z();

        if (currency.isReferencingCurrency(target, false)) {
            return giveCurrency(player, x, y, z, object, target);
        } else {
            Item item = player.getInventoryItem(object);

            if (item.getID() > 0) {
                if (item.isBound()) {
                    return ColourUtil.colourise(item.getName(), ColourUtil.item)
                            + " is bound to you!";
                } else {
                    player.removeInventoryItem(object);
                    Player p = players.getOnlinePlayer(target);

                    if (p.getID() > 0 && p.x() == x && p.y() == y && p.z() == z) {

                        p.giveItem(item);

                        Player[] playersInvolved = new Player[2];
                        playersInvolved[0] = player;
                        playersInvolved[1] = p;

                        out.broadcastToPlayer(p,
                                ColourUtil.colourise(player.getName(), ColourUtil.magenta)
                                + " gives you "
                                + ColourUtil.colourise(item.getName(), ColourUtil.cyan)
                                + ".");
                        out.broadcastLocalToPlayers(playersInvolved,
                                ColourUtil.colourise(player.getName(), ColourUtil.magenta)
                                + " gives "
                                + ColourUtil.colourise(item.getName(), ColourUtil.cyan)
                                + " to "
                                + ColourUtil.colourise(p.getName(), ColourUtil.magenta)
                                + ".");

                        return "You give "
                                + ColourUtil.colourise(item.getName(), ColourUtil.cyan)
                                + " to "
                                + ColourUtil.colourise(p.getName(), ColourUtil.magenta)
                                + ".";
                    } else {
                        return "You don't see any " + target + " here!";
                    }
                }
            } else {
                return "You don't have any " + object + " to give!";
            }
        }
    }

    private String giveCurrency(Player player, int x, int y, int z, String object, String target) {
        String[] tokens = object.split(" ");

        if (tokens.length == 1) {
            int amount = player.takeCurrency();
            return giveCurrencyTo(player, x, y, z, amount, target);
        } else if (tokens.length == 2 && currency.isReferencingCurrency(tokens[1], false)) {
            if (Util.isInteger(tokens[0])) {
                int amount = player.takeCurrency(Integer.parseInt(tokens[0]));
                return giveCurrencyTo(player, x, y, z, amount, target);
            } else {
                return "You must specify an amount of " + currency.getStatusID()
                        + ", or simply 'get " + currency.getStatusID() + "'.";
            }
        } else if (tokens.length > 2) {
            String tokensJoined = object.substring(tokens[0].length());
            if (Util.isInteger(tokens[0]) && currency.isReferencingCurrency(tokensJoined, false)) {
                int amount = player.takeCurrency(Integer.parseInt(tokens[0]));
                return giveCurrencyTo(player, x, y, z, amount, target);
            } else {
                return "You must specify an amount of " + currency.getStatusID()
                        + ", or simply 'get " + currency.getStatusID() + "'.";
            }
        } else {
            return "You must specify an amount of " + currency.getStatusID()
                    + ", or simply 'get " + currency.getStatusID() + "'.";
        }
    }

    private String giveCurrencyTo(Player player, int x, int y, int z, int amount, String target) {
        if (amount > 0) {
            Player p = players.getOnlinePlayer(target);

            if (p.getID() > 0 && p.x() == x && p.y() == y && p.z() == z) {

                p.giveCurrencyAmount(amount);
                Player[] playersInvolved = new Player[2];
                playersInvolved[0] = player;
                playersInvolved[1] = p;

                String currencyName;
                if (amount > 1) {
                    currencyName = amount + " " + currency.getPlural();
                } else {
                    currencyName = "a " + currency.getSingular();
                }

                out.broadcastToPlayer(p,
                        ColourUtil.colourise(player.getName(), ColourUtil.magenta)
                        + " gives you "
                        + ColourUtil.colourise(currencyName, ColourUtil.yellow)
                        + ".");
                out.broadcastLocalToPlayers(playersInvolved,
                        ColourUtil.colourise(player.getName(), ColourUtil.magenta)
                        + " gives "
                        + ColourUtil.colourise(currencyName, ColourUtil.yellow)
                        + " to "
                        + ColourUtil.colourise(p.getName(), ColourUtil.magenta)
                        + ".");

                return "You give "
                        + ColourUtil.colourise(currencyName, ColourUtil.yellow)
                        + " to "
                        + ColourUtil.colourise(p.getName(), ColourUtil.magenta)
                        + ".";
            } else {
                player.giveCurrencyAmount(amount);
                return "You don't see any " + target + " here!";
            }
        } else {
            return "You do not have any " + currency.getStatusID() + " to give!";
        }
    }
}
